﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ApiDoc.CodeSyntaxGenerators
{
    /// <summary>
    /// Factory for getting a ICodeSyntaxGenerator by its suppotred language.
    /// </summary>
    public partial class CodeSyntaxGeneratorFactory
    {
        /// <summary>
        /// Creates an ILanguageSyntaxGenerator for the passed in language.
        /// </summary>
        /// <param name="language"></param>
        /// <returns></returns>
        public ICodeSyntaxGenerator CreateGenerator(string language)
        {
            // Limit our search to just this assembly.
            var types = GetType().Assembly.GetTypes()
                .Where(item => item.GetCustomAttributes(typeof(CodeSyntaxGeneratorAttribute), true).Any())
                .ToList();
            foreach (var option in types) {
                var attributes = option.GetCustomAttributes(typeof(CodeSyntaxGeneratorAttribute), true).Cast<CodeSyntaxGeneratorAttribute>();
                foreach (var attribute in attributes) {
                    if (String.Compare(attribute.Language, language, StringComparison.OrdinalIgnoreCase) == 0) {
                        return (ICodeSyntaxGenerator)Activator.CreateInstance(option);
                    }
                }
            }

            // If we get here we couldn't find the language we wanted so return the default of C#
            return new Languages.CSharpCodeSyntaxGenerator();
        }

        /// <summary>
        /// Returns a list of supported languages.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<string> GetSupportedLanguages()
        {
            var ret = new List<string>();

            var types = GetType().Assembly.GetTypes()
                .Where(item => item.GetCustomAttributes(typeof(CodeSyntaxGeneratorAttribute), true).Any())
                .ToList();
            foreach (var option in types) {
                var attributes = option.GetCustomAttributes(typeof(CodeSyntaxGeneratorAttribute), true).Cast<CodeSyntaxGeneratorAttribute>();
                foreach (var attribute in attributes) {
                    ret.Add(attribute.Language);
                }
            }

            // Order the list as almost all coding code will want them in a sensible order.
            ret = ret.OrderBy(item => item).ToList();

            return ret;
        }
    }
}
